package cn.wolfcode.luowowo.member.service.impl;

import cn.wolfcode.luowowo.cache.prefix.VerifyCodeKeyPrefix;
import cn.wolfcode.luowowo.cache.service.IRedisService;
import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.cache.service.IVerifyCodeRedisService;
import cn.wolfcode.luowowo.common.exception.DisplayableException;
import cn.wolfcode.luowowo.common.util.AjaxResult;
import cn.wolfcode.luowowo.common.util.AssertUtil;
import cn.wolfcode.luowowo.common.util.MD5;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.mapper.UserInfoMapper;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StreamUtils;

import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.UUID;


@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Reference
    private IUserInfoRedisService userInfoRedisService;

    @Reference
    private IVerifyCodeRedisService verifyCodeService;

    @Reference
    private IRedisService redisService;

    @Override
    public UserInfo get(Long id) {
        return userInfoMapper.selectByPrimaryKey(id);
    }

    public List<UserInfo> list() {
        return userInfoMapper.selectAll();
    }

    public void regist(String phone, String nickname, String password, String rpassword, String verifyCode) throws DisplayableException {

        AssertUtil.hasLength(phone, "手机号码不能为空!");
        AssertUtil.hasLength(nickname, "昵称不能为空!");
        AssertUtil.hasLength(password, "密码不能为空!");
        AssertUtil.hasLength(rpassword, "确认密码不能为空!");
        AssertUtil.isEquals(password, rpassword, "两次输入密码不一致!");
        String code = verifyCodeService.getVerifyCode(phone);
        System.out.println(verifyCode);
        System.out.println(code);
        if (!code.equalsIgnoreCase(verifyCode)) {
            throw new DisplayableException("验证码错误!");
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setHeadImgUrl("/images/default.jpg");
        userInfo.setNickname(nickname);
        userInfo.setLevel(1);
        String encoder = MD5.encoder(password);
        userInfo.setPassword(encoder);
        userInfo.setPhone(phone);
        userInfo.setState(UserInfo.STATE_NORMAL);
        userInfoMapper.insert(userInfo);
    }

    public AjaxResult checkPhone(String phone) throws DisplayableException {
        AssertUtil.hasLength(phone, "手机号码不能为空!");
        AssertUtil.isMobile(phone, "手机号码格式不合法!");
        AjaxResult ajaxResult = new AjaxResult();
        boolean count = userInfoMapper.selectUserByPhone(phone) > 0;
        if (count) {
            ajaxResult = new AjaxResult("手机号码已经被注册了!");
        }
        return ajaxResult;
    }

    public String login(String username, String password) throws DisplayableException {
        UserInfo userInfo = userInfoMapper.selectUsernameAndpassword(username, MD5.encoder(password));
        if(userInfo==null){
            throw new DisplayableException("手机号码或密码输入不正确!");
        }


        //保存登录凭证token，并返回
        return createToke(userInfo);
    }

    /**
     * 创建token,并将token存入缓存中
     * @param userInfo
     * @return
     */
    private String createToke(UserInfo userInfo) {
        String token = UUID.randomUUID().toString().replace("-", "");

        //放置到redis中
        userInfoRedisService.setUserInfo(token,userInfo);

        return token;
    }

    public UserInfo getToken(String token) {
        UserInfo userInfo = userInfoRedisService.getUserInfo(token);
        return userInfo;
    }

    public void sendVerifyCode(String phone) throws DisplayableException {
        //1:生成4为验证码
        String code = UUID.randomUUID().toString().substring(0, 4);
        //2:发送到用户手机
        StringBuilder sb = new StringBuilder(80);
        sb.append("【懿夕网络】您的验证码是：").append(code);
//                .append(",请在"+Consts.VERIFY_CODE_VAI_TIME).append("分钟内完成验证!");

        //发送短信频率限制
        if (redisService.exists(VerifyCodeKeyPrefix.VAI_CODE, phone)) {
            throw new DisplayableException("短信已发送,请勿重复操作!");
        }

        try {
            verifyCodeService.setVerifyCode(phone, code);
            sendMsg(phone, sb);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DisplayableException("短信发送失败!");
        }
        //3.缓存

    }


    @Value("${msg.url}")
    private String msgUrl;

    @Value("${msg.appkey}")
    private String appkey;

    /**
     * @param phone
     * @param content
     */
    private void sendMsg(String phone, StringBuilder content) throws Exception {
        //指定访问地址
        URL url = new URL(msgUrl);
        //建立连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //设置请求方法
        connection.setRequestMethod("GET");
        //设置请求参数
        StringBuilder sb = new StringBuilder(100);
        sb.append("phone=").append(phone)
                .append("&content=").append(content)
                .append("&appkey=").append(appkey);
        //默认是false， 设置true表示输出参数
        System.out.println(sb);
        connection.setDoOutput(true);
        connection.getOutputStream().write(sb.toString().getBytes("UTF-8"));
        //请求连接
        connection.connect();
        //获取响应数据
        String resp = StreamUtils.copyToString(connection.getInputStream(), Charset.forName("UTF-8"));
        System.out.println(resp);
    }

    @Override
    public String update(UserInfo userInfo) {
        if ("".equals(userInfo.getHeadImgUrl())) {
            UserInfo oldUser = this.get(userInfo.getId());
            userInfo.setHeadImgUrl(oldUser.getHeadImgUrl());
        }
        userInfoMapper.updateByPrimaryKey(userInfo);
        //保存到redis中
        UserInfo u = userInfoMapper.selectByPrimaryKey(userInfo.getId());
        return this.createToke(u);
    }

    @Override
    public void revisePassword(String password, String code, String phone, String rpassword) {
        AssertUtil.hasLength(phone, "手机号码不能为空!");
        AssertUtil.hasLength(password, "密码不能为空!");
        AssertUtil.hasLength(rpassword, "确认密码不能为空!");
        AssertUtil.isEquals(password, rpassword, "两次输入密码不一致!");
        String verifyCode = verifyCodeService.getVerifyCode(phone);
        if (!verifyCode.equalsIgnoreCase(code)) {
            throw new DisplayableException("验证码错误");
        }
        String encoder = MD5.encoder(password);
        userInfoMapper.updatePasswordByPhone(phone, encoder);
    }

    @Override
    public UserInfo reviseEmail(String emailCode, String email, Long id, Long type) {
        AssertUtil.hasLength(email, "不能为空!");
        String verifyCode = verifyCodeService.getVerifyCode(email);
        if (!verifyCode.equalsIgnoreCase(emailCode)) {
            throw new DisplayableException("验证码错误");
        }
        //如果type为1的时候则是修改邮箱,如果是2时表示验证原手机
        if (type == 1) {
            userInfoMapper.updateEmailById(email, id);
        } else if (type == 2) {
            System.out.println("不做任何操作");
        } else if (type == 3) {
            userInfoMapper.updatePhoneByid(email, id);
        }
        return userInfoMapper.selectByPrimaryKey(id);
    }

    public void updateIntegral(Integer integral, Long id) {
         userInfoMapper.updateIntegralById(integral,id);
    }

    @Override
    public List<UserInfo> query(String keyword) {
        return userInfoMapper.selectByKeyword(keyword);
    }
}
